package de.gwtprime.server.servlets;

import java.io.IOException;
import java.io.StringWriter;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.TransformerFactoryConfigurationError;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.Document;
import org.w3c.dom.Element;

import de.gwtprime.server.model.Article;
import de.gwtprime.server.model.Question;
import de.gwtprime.server.servlets.CrawlServletHelper.CRAWLABLE_ENTITIES;
import de.gwtprime.shared.util.AppUtilsShared;

public class SiteMapGenerator extends HttpServlet{
	

	/**
	 * Format for sitemap entry timestamp
	 */
	static SimpleDateFormat sitemapDF = new SimpleDateFormat("yyyy-MM-dd");

	/**
	 * Serial version ID
	 */
	private static final long serialVersionUID = 1L;

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse response)
			throws ServletException, IOException {
		
		response.setContentType("application/xml");
		List<Article> articles = Article.loadLatestArticles(0);
		
		Document doc = null;
		try {
			doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
		} catch (ParserConfigurationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	    Element root = doc.createElement("urlset");
	   
	    root.setAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance");
	    root.setAttribute("xmlns", "http://www.sitemaps.org/schemas/sitemap/0.9");
	    root.setAttribute("xsi:schemaLocation", "http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd");
	    doc.appendChild(root);
	    
	    for (Article article : articles) {
	    	addEntry(doc, root, AppUtilsShared.generateGWTUrl(CRAWLABLE_ENTITIES.ARTICLE.getClassName(), article.getId()), new Date());
		}
	    
	    List<Question> questions = Question.getLatestQuestions(0);
	    for (Question question : questions) {
	    	
	    	addEntry(doc, root, AppUtilsShared.generateGWTUrl(CRAWLABLE_ENTITIES.Question.getClassName(), question.getId()), new Date());
		}
	    
	    writeTheXMLOut(response, doc);
	}

	private void writeTheXMLOut(HttpServletResponse response, Document doc)
			throws IOException {
		// create Transformer object
	    Transformer transformer = null;
		try {
			transformer = TransformerFactory.newInstance().newTransformer();
		} catch (TransformerConfigurationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (TransformerFactoryConfigurationError e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	    StringWriter writer = new StringWriter();
	    StreamResult result = new StreamResult(writer);
	    try {
			transformer.transform(new DOMSource(doc), result);
		} catch (TransformerException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	    
	    response.getWriter().println(writer.toString());
	}
	
	private static void addEntry(Document doc, Element root, String url, Date lastMod) {
		Element urlEl = doc.createElement("url");
	    root.appendChild(urlEl);
	    
	    Element locEl = doc.createElement("loc");
	    locEl.setTextContent(url);
	    
	    Element lastmodEl = doc.createElement("lastmod");
	    lastmodEl.setTextContent(sitemapDF.format(lastMod));
	    
	    urlEl.appendChild(locEl);
	    urlEl.appendChild(lastmodEl);
	}
	
}
